﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using itau.im.entidade;
using itau.im.dado;
using EnterpriseLibraryWrapper;
using System.Data;

namespace itau.im.negocio
{
    public class RelatorioRegraBS : IRelatorioRegraBS
    {
        public FiltroRelatorioRegras ObterFiltrosRelatorioRegras()
        {
            FiltroRelatorioRegras filtroRelatorioRegras = null;

            try
            {
                IRegraAtribuicaoDAO relatorioRegraDAO = DaoFactory.getRegraAtribuicaoDAO();
                IGrupoParametrosDAO relatorioGrupoParametroDAO = DaoFactory.getGrupoParametrosDAO();
                ICurvaDAO relatorioCurvaDAO = DaoFactory.getCurvaDAO();
                IProdutoFinanceiroDAO relatorioProdutoDAO = DaoFactory.getProdutoFinanceiroDAO();
                IMesaDB mesaDAO = DaoFactory.getMesaDAO();

                filtroRelatorioRegras = new FiltroRelatorioRegras();
                filtroRelatorioRegras.ListaGrupoParametro = new List<GrupoParametroAtribuicao>();
                filtroRelatorioRegras.ListaProdutoAlocacao = new List<ProdutoFinanceiroAlocacao>();
                filtroRelatorioRegras.ListaProdutoDerivado = new List<ProdutoFinanceiroDerivado>();
                filtroRelatorioRegras.ListaSituacao = new List<Situacao>();
                filtroRelatorioRegras.ListaSubMesasOperacao = new List<SubMesa>();
                filtroRelatorioRegras.ListaUsuarioAlteracao = new List<UsuarioAlteracao>();

                filtroRelatorioRegras.ListaSituacao.AddRange(relatorioRegraDAO.ObterSituacoesRegra());

                filtroRelatorioRegras.ListaSubMesasOperacao.AddRange(mesaDAO.ObterSubMesas(1));

                filtroRelatorioRegras.ListaGrupoParametro.AddRange(relatorioGrupoParametroDAO.ObterGruposDeParametros());

                foreach (GrupoParametroAtribuicao grupo in filtroRelatorioRegras.ListaGrupoParametro)
                {
                    filtroRelatorioRegras.ListaProdutoAlocacao.AddRange(relatorioGrupoParametroDAO.ObterProdutoFinanceiroAlocacaoPorGrupoParametro(grupo.CodigoGrupoParametroAtribuicao));
                }

                IList<ProdutoFinanceiro> produtosFinanceiros = new List<ProdutoFinanceiro>();
                produtosFinanceiros = relatorioProdutoDAO.ObterProdutosFinanceiros();
                List<ProdutoFinanceiroDerivado> listaProdutoDerivado = new List<ProdutoFinanceiroDerivado>();
                foreach (ProdutoFinanceiro itemProduto in produtosFinanceiros)
                {
                    listaProdutoDerivado.AddRange(relatorioProdutoDAO.ObterProdutosDerivadosPorProduto(itemProduto.CodigoProdutoFinanceiro));
                }
                filtroRelatorioRegras.ListaProdutoDerivado = listaProdutoDerivado;

                filtroRelatorioRegras.ListaUsuarioAlteracao.AddRange(relatorioRegraDAO.ObterUsuariosAlteracao());

                return filtroRelatorioRegras;

            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }

            return new FiltroRelatorioRegras();
        }

        public IList<RelatorioParametrosERegrasSaida> ConsultarRelatorioParametrosERegra(RelatorioParametrosERegrasEntrada filtroRelatorio, int numeroPagina, int qtdeRegistros)
        {
            IParametroAtribuicaoDAO relatorioParametroDAO = null;
            IProdutoFinanceiroDAO relatorioProdutoDAO = null;
            IRegraAtribuicaoDAO relatorioRegraDAO = null;
            IGrupoParametrosDAO relatorioGrupoParametroDAO = null;
            ICurvaDAO relatorioCurvaDAO = null;

            IList<RelatorioParametrosERegrasSaida> relatorio = null;

            IList<Curva> listaCurvas;
            IList<ParametroAtribuicao> listaParametros;
            IList<DominioParametroAtribuicao> listaRegistroDominio;

            try
            {
                relatorio = new List<RelatorioParametrosERegrasSaida>();

                relatorioParametroDAO = DaoFactory.getParametroAtribuicaoDAO();
                relatorioProdutoDAO = DaoFactory.getProdutoFinanceiroDAO();
                relatorioRegraDAO = DaoFactory.getRegraAtribuicaoDAO();
                relatorioGrupoParametroDAO = DaoFactory.getGrupoParametrosDAO();
                relatorioCurvaDAO = DaoFactory.getCurvaDAO();

                listaCurvas = relatorioCurvaDAO.ObterCurvas();
                listaParametros = relatorioParametroDAO.ObterParametros();
                listaRegistroDominio = relatorioParametroDAO.ObterRegistrosDominio();

                IList<RegraAtribuicaoCurvaRelatorio> regrasPorGrupo = relatorioRegraDAO.ObterRegrasAtribuicaoCurvaPorCodGrupoDataPAGINADO(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao, filtroRelatorio.DataInicioVigencia, filtroRelatorio.DataFimVigencia, numeroPagina, qtdeRegistros);
                IList<DominioParametroAtribuicao> dominiosPorGrupo = relatorioGrupoParametroDAO.ObterDominiosParametrosAtribuicaoPorGrupoVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                IList<ParametroAtribuicaoGrupoAlocacao> parametrosEndogenosPorGrupo = relatorioGrupoParametroDAO.ObterParametrosAtribuicaoGrupoAlocacaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                //IList<ProdutoFinanceiroDerivado> produtosExcecaoPorGrupo = relatorioGrupoParametroDAO.ObterProdutosFinanceirosDerivadosExcecaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);

                foreach (RegraAtribuicaoCurvaRelatorio itemRegra in regrasPorGrupo)
                {
                    if (filtroRelatorio.ListaSituacao.Exists(p => p.Codigo == itemRegra.CodigoSituacao))
                    {
                        RelatorioParametrosERegrasSaida novoItemRelatorio = new RelatorioParametrosERegrasSaida();
                        novoItemRelatorio.ListaParametros = new List<ParametroRelatorio>();

                        IList<ParametroRegra> parametrosPorRegra = relatorioRegraDAO.ObterParametrizacoesAtribuicaoPorCodigoRegraEDataVigenciaCompleto(itemRegra.CodigoRegraAtribuicaoCurva, itemRegra.DataInicioVigencia);
                        IEnumerable<ParametroRegra> parametrosExogenosPorRegra = parametrosPorRegra.Where(p => parametrosEndogenosPorGrupo.Count(q => q.CodigoParametroAtribuicao == p.CodigoParametroAtribuicao) == 0);

                        //Curva primeiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeira);
                        //Curva primeiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeiraComCaixa);
                        //Curva terceiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceira);
                        //Curva terceiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceiraComCaixa);
                        //ProdutoFinanceiroDerivado produtoExcecao = produtosExcecaoPorGrupo.FirstOrDefault(p => p.CodigoProdutoFinanceiroDerivado == itemRegra.CodigoProdutoFinanceiroExcecao);

                        //novoItemRelatorio.NomeCurva = primeiraCurva != null ? primeiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeCurvaComCaixa = primeiraCurvaCaixa != null ? primeiraCurvaCaixa.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeTerceiraCurva = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeTerceiraCurvaComCaixa = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;
                        novoItemRelatorio.NomeGrupoParametro = filtroRelatorio.GrupoParametro.NomeGrupoParametroAtribuicao;
                        novoItemRelatorio.CodigoGrupoParametroAtribuicao = filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao;
                        //novoItemRelatorio.NomeProdutoExcecao = produtoExcecao != null ? produtoExcecao.NomeProdutoFinanceiroDerivado : string.Empty;
                        novoItemRelatorio.Situacao = itemRegra.CodigoSituacao == 1 ? "Habilitada" : "Desabilitada";
                        novoItemRelatorio.DataInicioVigencia = itemRegra.DataInicioVigencia;
                        novoItemRelatorio.DataFimVigencia = itemRegra.DataFimVigencia;
                        novoItemRelatorio.NomeCurva = itemRegra.NomeCurvaPrimeira;
                        novoItemRelatorio.NomeCurvaComCaixa = itemRegra.NomePrimeiraCurvaComCaixa;
                        novoItemRelatorio.NomeTerceiraCurva = itemRegra.NomeTerceiraCurva;
                        novoItemRelatorio.NomeTerceiraCurvaComCaixa = itemRegra.NomeTerceiraCurvaComCaixa;
                        novoItemRelatorio.NomeProdutoExcecao = itemRegra.NomeProdutoDerivadoExcecao;

                        switch (itemRegra.CodigoTipoPrazo)
                        {
                            case 1:
                                novoItemRelatorio.CodigoTipoPrazo = "DU";
                                break;
                            case 2:
                                novoItemRelatorio.CodigoTipoPrazo = "DC";
                                break;
                            default:
                                novoItemRelatorio.CodigoTipoPrazo = string.Empty;
                                break;
                        }
                        novoItemRelatorio.QtdeDiasPrazo = itemRegra.QuantidadeDiasPrazo;

                        //NÃO APAGAR
                        //foreach (var itemEndogeno in parametrosEndogenosPorGrupo)
                        //{
                        //    ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemEndogeno.CodigoParametroAtribuicao);

                        //    novoItemRelatorio.ListaParametros.AddRange(ObterParametroEndogeno(itemEndogeno, parametroCompleto, dominiosPorGrupo));
                        //}

                        foreach (var itemExogeno in parametrosExogenosPorRegra)
                        {
                            ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao);

                            //IList<DominioParametroAtribuicao> dominioPorParametro = relatorioParametroDAO.ObterRegistrosDominioParametro(itemExogeno.CodigoParametroAtribuicao);
                            IList<DominioParametroAtribuicao> dominioPorParametro = listaRegistroDominio.Where(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao).ToList();

                            novoItemRelatorio.ListaParametros.AddRange(ObterParametroExogeno(itemExogeno, parametroCompleto, dominioPorParametro));
                        }

                        relatorio.Add(novoItemRelatorio);
                    }

                }

                return relatorio;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }

            return null;
        }

        public IList<RelatorioCombinacoesDominioSaida> ConsultarRelatorioCombinacoesDominios(RelatorioCombinacoesDominioEntrada filtroRelatorio, int numeroPagina, int qtdeRegistros)
        {
            IParametroAtribuicaoDAO relatorioParametroDAO = null;
            IProdutoFinanceiroDAO relatorioProdutoDAO = null;
            IRegraAtribuicaoDAO relatorioRegraDAO = null;
            IGrupoParametrosDAO relatorioGrupoParametroDAO = null;
            ICurvaDAO relatorioCurvaDAO = null;

            IList<RelatorioCombinacoesDominioSaida> relatorioCombinacoesDominioSaida = null;

            IList<Curva> listaCurvas;
            IList<ParametroAtribuicao> listaParametros;
            IList<DominioParametroAtribuicao> listaRegistroDominio;

            try
            {
                relatorioCombinacoesDominioSaida = new List<RelatorioCombinacoesDominioSaida>();

                relatorioParametroDAO = DaoFactory.getParametroAtribuicaoDAO();
                relatorioProdutoDAO = DaoFactory.getProdutoFinanceiroDAO();
                relatorioRegraDAO = DaoFactory.getRegraAtribuicaoDAO();
                relatorioGrupoParametroDAO = DaoFactory.getGrupoParametrosDAO();
                relatorioCurvaDAO = DaoFactory.getCurvaDAO();

                listaCurvas = relatorioCurvaDAO.ObterCurvas();
                listaParametros = relatorioParametroDAO.ObterParametros();
                listaRegistroDominio = relatorioParametroDAO.ObterRegistrosDominio();

                IList<RegraAtribuicaoCurvaRelatorio> regrasPorGrupo = relatorioRegraDAO.ObterRegrasAtribuicaoCurvaPorCodGrupoDataPAGINADO(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao, filtroRelatorio.DataInicioVigencia, filtroRelatorio.DataFimVigencia, numeroPagina, qtdeRegistros);
                IList<DominioParametroAtribuicao> dominiosPorGrupo = relatorioGrupoParametroDAO.ObterDominiosParametrosAtribuicaoPorGrupoVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                IList<ParametroAtribuicaoGrupoAlocacao> parametrosEndogenosPorGrupo = relatorioGrupoParametroDAO.ObterParametrosAtribuicaoGrupoAlocacaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                //IList<ProdutoFinanceiroDerivado> produtosExcecaoPorGrupo = relatorioGrupoParametroDAO.ObterProdutosFinanceirosDerivadosExcecaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);

                foreach (RegraAtribuicaoCurvaRelatorio itemRegra in regrasPorGrupo)
                {
                    //Trata apenas as regras com SubProduto de Exceção listado no filtro SubProdutos
                    //if (filtroRelatorio.ListaProdutoAlocacao.Exists(p => p.CodigoProdutoFinanceiroDerivado == itemRegra.CodigoProdutoFinanceiroExcecao))
                    {
                        RelatorioCombinacoesDominioSaida novoItemRelatorio = new RelatorioCombinacoesDominioSaida();
                        novoItemRelatorio.ListaParametrosExogenos = new List<ParametroRelatorio>();
                        novoItemRelatorio.ListaParametrosEndogenos = new List<ParametroRelatorio>();

                        IList<ParametroRegra> parametrosPorRegra = relatorioRegraDAO.ObterParametrizacoesAtribuicaoPorCodigoRegraEDataVigenciaCompleto(itemRegra.CodigoRegraAtribuicaoCurva, itemRegra.DataInicioVigencia);
                        IEnumerable<ParametroRegra> parametrosExogenosPorRegra = parametrosPorRegra.Where(p => parametrosEndogenosPorGrupo.Count(q => q.CodigoParametroAtribuicao == p.CodigoParametroAtribuicao) == 0);

                        //Curva primeiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeira);
                        //Curva primeiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeiraComCaixa);
                        //Curva terceiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceira);
                        //Curva terceiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceiraComCaixa);
                        //ProdutoFinanceiroDerivado produtoExcecao = produtosExcecaoPorGrupo.FirstOrDefault(p => p.CodigoProdutoFinanceiroDerivado == itemRegra.CodigoProdutoFinanceiroExcecao);

                        //novoItemRelatorio.NomeCurva = primeiraCurva != null ? primeiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeCurvaComCaixa = primeiraCurvaCaixa != null ? primeiraCurvaCaixa.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeTerceiraCurva = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeTerceiraCurvaComCaixa = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeProdutoExcecao = produtoExcecao != null ? produtoExcecao.NomeProdutoFinanceiroDerivado : string.Empty;

                        novoItemRelatorio.CodigoGrupoParametro = filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao;
                        novoItemRelatorio.NomeGrupoParametro = filtroRelatorio.GrupoParametro.NomeGrupoParametroAtribuicao;

                        novoItemRelatorio.Situacao = itemRegra.CodigoSituacao == 1 ? "Habilitada" : "Desabilitada";
                        novoItemRelatorio.DataInicioVigencia = itemRegra.DataInicioVigencia;
                        novoItemRelatorio.DataFimVigencia = itemRegra.DataFimVigencia;
                        novoItemRelatorio.NomeCurva = itemRegra.NomeCurvaPrimeira;
                        novoItemRelatorio.NomeCurvaComCaixa = itemRegra.NomePrimeiraCurvaComCaixa;
                        novoItemRelatorio.NomeTerceiraCurva = itemRegra.NomeTerceiraCurva;
                        novoItemRelatorio.NomeTerceiraCurvaComCaixa = itemRegra.NomeTerceiraCurvaComCaixa;
                        novoItemRelatorio.NomeProdutoExcecao = itemRegra.NomeProdutoDerivadoExcecao;
                        novoItemRelatorio.IndicadorExiste = "SIM";

                        switch (itemRegra.CodigoTipoPrazo)
                        {
                            case 1:
                                novoItemRelatorio.CodigoTipoPrazo = "DU";
                                break;
                            case 2:
                                novoItemRelatorio.CodigoTipoPrazo = "DC";
                                break;
                            default:
                                novoItemRelatorio.CodigoTipoPrazo = string.Empty;
                                break;
                        }
                        novoItemRelatorio.QtdeDiasPrazo = itemRegra.QuantidadeDiasPrazo;

                        //NÃO APAGAR
                        //foreach (var itemEndogeno in parametrosEndogenosPorGrupo)
                        //{
                        //    ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemEndogeno.CodigoParametroAtribuicao);

                        //    novoItemRelatorio.ListaParametrosEndogenos.AddRange(ObterParametroEndogeno(itemEndogeno, parametroCompleto, dominiosPorGrupo));
                        //}

                        foreach (var itemExogeno in parametrosExogenosPorRegra)
                        {
                            ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao);

                            IList<DominioParametroAtribuicao> dominioPorParametro = relatorioParametroDAO.ObterRegistrosDominioParametro(itemExogeno.CodigoParametroAtribuicao);

                            novoItemRelatorio.ListaParametrosExogenos.AddRange(ObterParametroExogeno(itemExogeno, parametroCompleto, dominioPorParametro));
                        }

                        relatorioCombinacoesDominioSaida.Add(novoItemRelatorio);
                    }

                }

                return relatorioCombinacoesDominioSaida;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }

            return null;
        }

        public IList<RelatorioHistAlteracaoRegrasSaida> ConsultarRelatorioHistoricoAlteracao(RelatorioHistAlteracaoRegrasEntrada filtroRelatorio, int numeroPagina, int qtdeRegistros)
        {
            IParametroAtribuicaoDAO relatorioParametroDAO = null;
            IProdutoFinanceiroDAO relatorioProdutoDAO = null;
            IRegraAtribuicaoDAO relatorioRegraDAO = null;
            IGrupoParametrosDAO relatorioGrupoParametroDAO = null;
            ICurvaDAO relatorioCurvaDAO = null;

            IList<RelatorioHistAlteracaoRegrasSaida> relatorioHistAlteracaoRegrasSaida = null;

            IList<Curva> listaCurvas;
            IList<ParametroAtribuicao> listaParametros;
            IList<GrupoParametroAtribuicao> listaGrupoParametro;
            IList<DominioParametroAtribuicao> listaRegistroDominio;

            try
            {
                relatorioHistAlteracaoRegrasSaida = new List<RelatorioHistAlteracaoRegrasSaida>();

                relatorioParametroDAO = DaoFactory.getParametroAtribuicaoDAO();
                relatorioProdutoDAO = DaoFactory.getProdutoFinanceiroDAO();
                relatorioRegraDAO = DaoFactory.getRegraAtribuicaoDAO();
                relatorioGrupoParametroDAO = DaoFactory.getGrupoParametrosDAO();
                relatorioCurvaDAO = DaoFactory.getCurvaDAO();

                listaCurvas = relatorioCurvaDAO.ObterCurvas();
                listaParametros = relatorioParametroDAO.ObterParametros();
                listaGrupoParametro = relatorioGrupoParametroDAO.ObterGruposDeParametros();
                listaRegistroDominio = relatorioParametroDAO.ObterRegistrosDominio();

                IList<RegraAtribuicaoCurvaRelatorio> regrasPorUsuario = relatorioRegraDAO.ObterRegrasAtribuicaoCurvaPorUsuarioEDataAlteracaoPAGINADO(filtroRelatorio.UsuarioAlteracao.codigo, filtroRelatorio.DataAlteracaoInicio, filtroRelatorio.DataAlteracaoFim, numeroPagina, qtdeRegistros);

                var agrupamento = from grupo in regrasPorUsuario
                                  group grupo by grupo.CodigoGrupoParametroAtribuicao;

                foreach (var item in agrupamento)
                {
                    int codigoGrupoParametro = item.ToList()[0].CodigoGrupoParametroAtribuicao;
                    IList<DominioParametroAtribuicao> dominiosPorGrupo = relatorioGrupoParametroDAO.ObterDominiosParametrosAtribuicaoPorGrupoVigente(codigoGrupoParametro);
                    IList<ParametroAtribuicaoGrupoAlocacao> parametrosEndogenosPorGrupo = relatorioGrupoParametroDAO.ObterParametrosAtribuicaoGrupoAlocacaoPorGrupoParametrosVigente(codigoGrupoParametro);
                    //IList<ProdutoFinanceiroDerivado> produtosExcecaoPorGrupo = relatorioGrupoParametroDAO.ObterProdutosFinanceirosDerivadosExcecaoPorGrupoParametrosVigente(codigoGrupoParametro);

                    foreach (var itemRegra in item)
                    {
                        Curva primeiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeira);
                        GrupoParametroAtribuicao grupoParametro = listaGrupoParametro.FirstOrDefault(p => p.CodigoGrupoParametroAtribuicao == itemRegra.CodigoGrupoParametroAtribuicao);
                        //ProdutoFinanceiroDerivado produtoExcecao = produtosExcecaoPorGrupo.FirstOrDefault(p => p.CodigoProdutoFinanceiroDerivado == itemRegra.CodigoProdutoFinanceiroExcecao);

                        RelatorioHistAlteracaoRegrasSaida novoItemRelatorio = new RelatorioHistAlteracaoRegrasSaida();
                        novoItemRelatorio.ListaParametros = new List<ParametroRelatorio>();

                        IList<ParametroRegra> parametrosPorRegra = relatorioRegraDAO.ObterParametrizacoesAtribuicaoPorCodigoRegraEDataVigenciaCompleto(itemRegra.CodigoRegraAtribuicaoCurva, itemRegra.DataInicioVigencia);
                        IEnumerable<ParametroRegra> parametrosExogenosPorRegra = parametrosPorRegra.Where(p => parametrosEndogenosPorGrupo.Count(q => q.CodigoParametroAtribuicao == p.CodigoParametroAtribuicao) == 0);

                        //novoItemRelatorio.NomeCurva = primeiraCurva != null ? primeiraCurva.NomeCurva : string.Empty;

                        //novoItemRelatorio.NomeProdutoExcecao = produtoExcecao != null ? produtoExcecao.NomeProdutoFinanceiroDerivado : string.Empty;

                        if (itemRegra.CodigoSituacao == 1)
                            novoItemRelatorio.Situacao = "Habilitada";
                        else if (itemRegra.CodigoSituacao == 2)
                            novoItemRelatorio.Situacao = "Desabilitada";
                        else
                            novoItemRelatorio.Situacao = string.Empty;

                        novoItemRelatorio.NomeGrupoParametro = grupoParametro.NomeGrupoParametroAtribuicao;
                        novoItemRelatorio.CodigoGrupoParametroAtribuicao = grupoParametro.CodigoGrupoParametroAtribuicao;
                        novoItemRelatorio.DataInicioVigencia = itemRegra.DataInicioVigencia;
                        novoItemRelatorio.DataFimVigencia = itemRegra.DataFimVigencia;
                        novoItemRelatorio.NomeCurva = itemRegra.NomeCurvaPrimeira;
                        novoItemRelatorio.NomeProdutoExcecao = itemRegra.NomeProdutoDerivadoExcecao;

                        switch (itemRegra.CodigoTipoPrazo)
                        {
                            case 1:
                                novoItemRelatorio.CodigoTipoPrazo = "DU";
                                break;
                            case 2:
                                novoItemRelatorio.CodigoTipoPrazo = "DC";
                                break;
                            default:
                                novoItemRelatorio.CodigoTipoPrazo = string.Empty;
                                break;
                        }
                        novoItemRelatorio.QtdeDiasPrazo = itemRegra.QuantidadeDiasPrazo;

                        //NAO APAGAR
                        //foreach (var itemEndogeno in parametrosEndogenosPorGrupo)
                        //{
                        //    ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemEndogeno.CodigoParametroAtribuicao);

                        //    novoItemRelatorio.ListaParametros.AddRange(ObterParametroEndogeno(itemEndogeno, parametroCompleto, dominiosPorGrupo));
                        //}

                        foreach (var itemExogeno in parametrosExogenosPorRegra)
                        {
                            ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao);

                            //IList<DominioParametroAtribuicao> dominioPorParametro = relatorioParametroDAO.ObterRegistrosDominioParametro(itemExogeno.CodigoParametroAtribuicao);
                            IList<DominioParametroAtribuicao> dominioPorParametro = listaRegistroDominio.Where(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao).ToList();

                            novoItemRelatorio.ListaParametros.AddRange(ObterParametroExogeno(itemExogeno, parametroCompleto, dominioPorParametro));
                        }

                        relatorioHistAlteracaoRegrasSaida.Add(novoItemRelatorio);


                    }
                }

                return relatorioHistAlteracaoRegrasSaida;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }

            return null;
        }

        public IList<RelatorioListagemSubProdutosSaida> ConsultarRelatorioListagemSubProduto(RelatorioListagemSubProdutosEntrada filtroRelatorio, int numeroPagina, int qtdeRegistros)
        {
            IParametroAtribuicaoDAO relatorioParametroDAO = null;
            IProdutoFinanceiroDAO relatorioProdutoDAO = null;
            IRegraAtribuicaoDAO relatorioRegraDAO = null;
            IGrupoParametrosDAO relatorioGrupoParametroDAO = null;
            ICurvaDAO relatorioCurvaDAO = null;

            IList<RelatorioListagemSubProdutosSaida> relatorioListagemSubProdutosSaida = null;

            IList<Curva> listaCurvas;
            IList<ParametroAtribuicao> listaParametros;
            IList<DominioParametroAtribuicao> listaRegistroDominio;

            try
            {
                relatorioListagemSubProdutosSaida = new List<RelatorioListagemSubProdutosSaida>();

                relatorioParametroDAO = DaoFactory.getParametroAtribuicaoDAO();
                relatorioProdutoDAO = DaoFactory.getProdutoFinanceiroDAO();
                relatorioRegraDAO = DaoFactory.getRegraAtribuicaoDAO();
                relatorioGrupoParametroDAO = DaoFactory.getGrupoParametrosDAO();
                relatorioCurvaDAO = DaoFactory.getCurvaDAO();

                listaCurvas = relatorioCurvaDAO.ObterCurvas();
                listaParametros = relatorioParametroDAO.ObterParametros();
                listaRegistroDominio = relatorioParametroDAO.ObterRegistrosDominio();

                IList<RegraAtribuicaoCurvaRelatorio> regrasPorGrupo = relatorioRegraDAO.ObterRegrasAtribuicaoCurvaPorCodGrupoDataPAGINADO(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao, filtroRelatorio.DataInicioVigencia, filtroRelatorio.DataFimVigencia, numeroPagina, qtdeRegistros);
                IList<DominioParametroAtribuicao> dominiosPorGrupo = relatorioGrupoParametroDAO.ObterDominiosParametrosAtribuicaoPorGrupoVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                IList<ParametroAtribuicaoGrupoAlocacao> parametrosEndogenosPorGrupo = relatorioGrupoParametroDAO.ObterParametrosAtribuicaoGrupoAlocacaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                //IList<ProdutoFinanceiroDerivado> produtosExcecaoPorGrupo = relatorioGrupoParametroDAO.ObterProdutosFinanceirosDerivadosExcecaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);

                foreach (RegraAtribuicaoCurvaRelatorio itemRegra in regrasPorGrupo)
                {
                    //Trata apenas as regras com SubProduto de Exceção listado no filtro SubProdutos
                    //if (filtroRelatorio.ListaProdutoAlocacao.Exists(p => p.CodigoProdutoFinanceiroDerivado == itemRegra.CodigoProdutoFinanceiroExcecao))
                    {
                        RelatorioListagemSubProdutosSaida novoItemRelatorio = new RelatorioListagemSubProdutosSaida();
                        novoItemRelatorio.ListaParametros = new List<ParametroRelatorio>();

                        IList<ParametroRegra> parametrosPorRegra = relatorioRegraDAO.ObterParametrizacoesAtribuicaoPorCodigoRegraEDataVigenciaCompleto(itemRegra.CodigoRegraAtribuicaoCurva, itemRegra.DataInicioVigencia);
                        IEnumerable<ParametroRegra> parametrosExogenosPorRegra = parametrosPorRegra.Where(p => parametrosEndogenosPorGrupo.Count(q => q.CodigoParametroAtribuicao == p.CodigoParametroAtribuicao) == 0);

                        //Curva primeiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeira);
                        //Curva primeiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeiraComCaixa);
                        //Curva terceiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceira);
                        //Curva terceiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceiraComCaixa);
                        //ProdutoFinanceiroDerivado produtoExcecao = produtosExcecaoPorGrupo.FirstOrDefault(p => p.CodigoProdutoFinanceiroDerivado == itemRegra.CodigoProdutoFinanceiroExcecao);

                        //novoItemRelatorio.NomeCurva = primeiraCurva != null ? primeiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeCurvaComCaixa = primeiraCurvaCaixa != null ? primeiraCurvaCaixa.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeTerceiraCurva = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeTerceiraCurvaComCaixa = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;
                        //
                        //novoItemRelatorio.NomeProdutoExcecao = produtoExcecao != null ? produtoExcecao.NomeProdutoFinanceiroDerivado : string.Empty;

                        novoItemRelatorio.CodigoGrupoParametroAtribuicao = filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao;
                        novoItemRelatorio.NomeGrupoParametro = filtroRelatorio.GrupoParametro.NomeGrupoParametroAtribuicao;
                        novoItemRelatorio.Situacao = itemRegra.CodigoSituacao == 1 ? "Habilitada" : "Desabilitada";
                        novoItemRelatorio.DataInicioVigencia = itemRegra.DataInicioVigencia;
                        novoItemRelatorio.DataFimVigencia = itemRegra.DataFimVigencia;
                        novoItemRelatorio.NomeCurva = itemRegra.NomeCurvaPrimeira;
                        novoItemRelatorio.NomeCurvaComCaixa = itemRegra.NomePrimeiraCurvaComCaixa;
                        novoItemRelatorio.NomeTerceiraCurva = itemRegra.NomeTerceiraCurva;
                        novoItemRelatorio.NomeTerceiraCurvaComCaixa = itemRegra.NomeTerceiraCurvaComCaixa;
                        novoItemRelatorio.NomeProdutoExcecao = itemRegra.NomeProdutoDerivadoExcecao;
                        novoItemRelatorio.CodigoProdutoExcecao = itemRegra.CodigoProdutoFinanceiroDerivado;

                        switch (itemRegra.CodigoTipoPrazo)
                        {
                            case 1:
                                novoItemRelatorio.CodigoTipoPrazo = "DU";
                                break;
                            case 2:
                                novoItemRelatorio.CodigoTipoPrazo = "DC";
                                break;
                            default:
                                novoItemRelatorio.CodigoTipoPrazo = string.Empty;
                                break;
                        }
                        novoItemRelatorio.QtdeDiasPrazo = itemRegra.QuantidadeDiasPrazo;

                        //NÃO COMENTAR
                        //foreach (var itemEndogeno in parametrosEndogenosPorGrupo)
                        //{
                        //    ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemEndogeno.CodigoParametroAtribuicao);

                        //    novoItemRelatorio.ListaParametros.AddRange(ObterParametroEndogeno(itemEndogeno, parametroCompleto, dominiosPorGrupo));
                        //}

                        foreach (var itemExogeno in parametrosExogenosPorRegra)
                        {
                            ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao);

                            //IList<DominioParametroAtribuicao> dominioPorParametro = relatorioParametroDAO.ObterRegistrosDominioParametro(itemExogeno.CodigoParametroAtribuicao);
                            IList<DominioParametroAtribuicao> dominioPorParametro = listaRegistroDominio.Where(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao).ToList();

                            novoItemRelatorio.ListaParametros.AddRange(ObterParametroExogeno(itemExogeno, parametroCompleto, dominioPorParametro));
                        }

                        relatorioListagemSubProdutosSaida.Add(novoItemRelatorio);
                    }

                }

                return relatorioListagemSubProdutosSaida;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }

            return null;
        }

        public IList<RelatorioRegraAprecamentoSaida> ConsultarRelatorioRegraAprecamento(RelatorioRegraAprecamentoEntrada filtroRelatorio, int numeroPagina, int qtdeRegistros)
        {
            IParametroAtribuicaoDAO relatorioParametroDAO = null;
            IProdutoFinanceiroDAO relatorioProdutoDAO = null;
            IRegraAtribuicaoDAO relatorioRegraDAO = null;
            IGrupoParametrosDAO relatorioGrupoParametroDAO = null;
            ICurvaDAO relatorioCurvaDAO = null;
            IMesaDB mesaDAO = null;

            IList<RelatorioRegraAprecamentoSaida> relatorioRegraAprecamentoSaida = null;

            IList<Curva> listaCurvas;
            IList<ParametroAtribuicao> listaParametros;
            IList<SubMesa> listaMesaOrigem;
            IList<DominioParametroAtribuicao> listaRegistroDominio;

            try
            {
                relatorioRegraAprecamentoSaida = new List<RelatorioRegraAprecamentoSaida>();

                relatorioParametroDAO = DaoFactory.getParametroAtribuicaoDAO();
                relatorioProdutoDAO = DaoFactory.getProdutoFinanceiroDAO();
                relatorioRegraDAO = DaoFactory.getRegraAtribuicaoDAO();
                relatorioGrupoParametroDAO = DaoFactory.getGrupoParametrosDAO();
                relatorioCurvaDAO = DaoFactory.getCurvaDAO();
                mesaDAO = DaoFactory.getMesaDAO();

                listaCurvas = relatorioCurvaDAO.ObterCurvas();
                listaParametros = relatorioParametroDAO.ObterParametros();
                listaMesaOrigem = mesaDAO.ObterSubMesas(1);
                listaRegistroDominio = relatorioParametroDAO.ObterRegistrosDominio();

                IList<RegraAtribuicaoCurvaRelatorio> regrasPorGrupo = relatorioRegraDAO.ObterRegrasAtribuicaoCurvaPorCodGrupoDataPAGINADO(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao, filtroRelatorio.DataInicioVigencia, filtroRelatorio.DataFimVigencia, numeroPagina, qtdeRegistros);
                IList<DominioParametroAtribuicao> dominiosPorGrupo = relatorioGrupoParametroDAO.ObterDominiosParametrosAtribuicaoPorGrupoVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                IList<ParametroAtribuicaoGrupoAlocacao> parametrosEndogenosPorGrupo = relatorioGrupoParametroDAO.ObterParametrosAtribuicaoGrupoAlocacaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                //IList<ProdutoFinanceiroDerivado> produtosExcecaoPorGrupo = relatorioGrupoParametroDAO.ObterProdutosFinanceirosDerivadosExcecaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);

                foreach (RegraAtribuicaoCurvaRelatorio itemRegra in regrasPorGrupo)
                {
                    RelatorioRegraAprecamentoSaida novoItemRelatorio = new RelatorioRegraAprecamentoSaida();
                    novoItemRelatorio.ListaParametros = new List<ParametroRelatorio>();
                    SubMesa mesaOrigemPrimeiraCurva = new SubMesa();
                    SubMesa mesaOrigemTerceiraCurva = new SubMesa();

                    IList<ParametroRegra> parametrosPorRegra = relatorioRegraDAO.ObterParametrizacoesAtribuicaoPorCodigoRegraEDataVigenciaCompleto(itemRegra.CodigoRegraAtribuicaoCurva, itemRegra.DataInicioVigencia);
                    IEnumerable<ParametroRegra> parametrosExogenosPorRegra = parametrosPorRegra.Where(p => parametrosEndogenosPorGrupo.Count(q => q.CodigoParametroAtribuicao == p.CodigoParametroAtribuicao) == 0);

                    Curva primeiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeira);
                    if (primeiraCurva != null)
                        mesaOrigemPrimeiraCurva = listaMesaOrigem.FirstOrDefault(p => p.CodigoSubMesa == primeiraCurva.CodigoSubMesaOperacao);

                    //Curva primeiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeiraComCaixa);

                    Curva terceiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceira);
                    if (terceiraCurva != null)
                        mesaOrigemTerceiraCurva = listaMesaOrigem.FirstOrDefault(p => p.CodigoSubMesa == terceiraCurva.CodigoSubMesaOperacao);

                    //Curva terceiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceiraComCaixa);

                    //ProdutoFinanceiroDerivado produtoExcecao = produtosExcecaoPorGrupo.FirstOrDefault(p => p.CodigoProdutoFinanceiroDerivado == itemRegra.CodigoProdutoFinanceiroExcecao);

                    //novoItemRelatorio.NomeCurva = primeiraCurva != null ? primeiraCurva.NomeCurva : string.Empty;

                    if (mesaOrigemPrimeiraCurva != null)
                        novoItemRelatorio.MesaOrigemCurva = mesaOrigemPrimeiraCurva.Nome;

                    //novoItemRelatorio.NomeCurvaComCaixa = primeiraCurvaCaixa != null ? primeiraCurvaCaixa.NomeCurva : string.Empty;
                    //novoItemRelatorio.NomeTerceiraCurva = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;

                    if (mesaOrigemTerceiraCurva != null)
                        novoItemRelatorio.MesaOrigemTerceiraCurva = mesaOrigemTerceiraCurva.Nome;

                    //novoItemRelatorio.NomeTerceiraCurvaComCaixa = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;

                    //novoItemRelatorio.NomeProdutoExcecao = produtoExcecao != null ? produtoExcecao.NomeProdutoFinanceiroDerivado : string.Empty;

                    novoItemRelatorio.NomeGrupoParametro = filtroRelatorio.GrupoParametro.NomeGrupoParametroAtribuicao;
                    novoItemRelatorio.CodigoGrupoParametroAtribuicao = filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao;
                    novoItemRelatorio.Situacao = itemRegra.CodigoSituacao == 1 ? "Habilitada" : "Desabilitada";
                    novoItemRelatorio.DataInicioVigencia = itemRegra.DataInicioVigencia;
                    novoItemRelatorio.DataFimVigencia = itemRegra.DataFimVigencia;
                    novoItemRelatorio.NomeCurva = itemRegra.NomeCurvaPrimeira;
                    novoItemRelatorio.NomeCurvaComCaixa = itemRegra.NomePrimeiraCurvaComCaixa;
                    novoItemRelatorio.NomeTerceiraCurva = itemRegra.NomeTerceiraCurva;
                    novoItemRelatorio.NomeTerceiraCurvaComCaixa = itemRegra.NomeTerceiraCurvaComCaixa;
                    novoItemRelatorio.NomeProdutoExcecao = itemRegra.NomeProdutoDerivadoExcecao;

                    switch (itemRegra.CodigoTipoPrazo)
                    {
                        case 1:
                            novoItemRelatorio.CodigoTipoPrazo = "DU";
                            break;
                        case 2:
                            novoItemRelatorio.CodigoTipoPrazo = "DC";
                            break;
                        default:
                            novoItemRelatorio.CodigoTipoPrazo = string.Empty;
                            break;
                    }
                    novoItemRelatorio.QtdeDiasPrazo = itemRegra.QuantidadeDiasPrazo;

                    //NÃO APAGAR
                    //foreach (var itemEndogeno in parametrosEndogenosPorGrupo)
                    //{
                    //    ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemEndogeno.CodigoParametroAtribuicao);

                    //    novoItemRelatorio.ListaParametros.AddRange(ObterParametroEndogeno(itemEndogeno, parametroCompleto, dominiosPorGrupo));
                    //}

                    foreach (var itemExogeno in parametrosExogenosPorRegra)
                    {
                        ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao);

                        //IList<DominioParametroAtribuicao> dominioPorParametro = relatorioParametroDAO.ObterRegistrosDominioParametro(itemExogeno.CodigoParametroAtribuicao);
                        IList<DominioParametroAtribuicao> dominioPorParametro = listaRegistroDominio.Where(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao).ToList();

                        novoItemRelatorio.ListaParametros.AddRange(ObterParametroExogeno(itemExogeno, parametroCompleto, dominioPorParametro));
                    }

                    relatorioRegraAprecamentoSaida.Add(novoItemRelatorio);


                }

                return relatorioRegraAprecamentoSaida;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }

            return null;
        }

        public IList<RelatorioSegregacaoRegrasSaida> ConsultarRelatorioSegregacaoRegras(RelatorioSegregacaoRegrasEntrada filtroRelatorio, int numeroPagina, int qtdeRegistros)
        {
            IParametroAtribuicaoDAO relatorioParametroDAO = null;
            IProdutoFinanceiroDAO relatorioProdutoDAO = null;
            IRegraAtribuicaoDAO relatorioRegraDAO = null;
            IGrupoParametrosDAO relatorioGrupoParametroDAO = null;
            ICurvaDAO relatorioCurvaDAO = null;

            IList<RelatorioSegregacaoRegrasSaida> relatorioSegregacaoRegrasSaida = null;

            IList<Curva> listaCurvas;
            IList<ParametroAtribuicao> listaParametros;
            IList<DominioParametroAtribuicao> listaRegistroDominio;

            try
            {
                relatorioSegregacaoRegrasSaida = new List<RelatorioSegregacaoRegrasSaida>();

                relatorioParametroDAO = DaoFactory.getParametroAtribuicaoDAO();
                relatorioProdutoDAO = DaoFactory.getProdutoFinanceiroDAO();
                relatorioRegraDAO = DaoFactory.getRegraAtribuicaoDAO();
                relatorioGrupoParametroDAO = DaoFactory.getGrupoParametrosDAO();
                relatorioCurvaDAO = DaoFactory.getCurvaDAO();

                listaCurvas = relatorioCurvaDAO.ObterCurvas();
                listaParametros = relatorioParametroDAO.ObterParametros();
                listaRegistroDominio = relatorioParametroDAO.ObterRegistrosDominio();

                IList<RegraAtribuicaoCurvaRelatorio> regrasPorGrupo = relatorioRegraDAO.ObterRegrasAtribuicaoCurvaPorCodGrupoDataPAGINADO(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao, filtroRelatorio.DataInicioVigencia, filtroRelatorio.DataFimVigencia, numeroPagina, qtdeRegistros);
                IList<DominioParametroAtribuicao> dominiosPorGrupo = relatorioGrupoParametroDAO.ObterDominiosParametrosAtribuicaoPorGrupoVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                IList<ParametroAtribuicaoGrupoAlocacao> parametrosEndogenosPorGrupo = relatorioGrupoParametroDAO.ObterParametrosAtribuicaoGrupoAlocacaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);
                IList<ProdutoFinanceiroDerivado> produtosExcecaoPorGrupo = relatorioGrupoParametroDAO.ObterProdutosFinanceirosDerivadosExcecaoPorGrupoParametrosVigente(filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao);

                foreach (RegraAtribuicaoCurvaRelatorio itemRegra in regrasPorGrupo)
                {
                    Curva primeiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeira);
                    if (primeiraCurva != null && filtroRelatorio.ListaMesaOrigem.Exists(p => p.CodigoSubMesa == primeiraCurva.CodigoSubMesaOperacao))
                    {
                        RelatorioSegregacaoRegrasSaida novoItemRelatorio = new RelatorioSegregacaoRegrasSaida();
                        novoItemRelatorio.ListaParametros = new List<ParametroRelatorio>();

                        IList<ParametroRegra> parametrosPorRegra = relatorioRegraDAO.ObterParametrizacoesAtribuicaoPorCodigoRegraEDataVigenciaCompleto(itemRegra.CodigoRegraAtribuicaoCurva, itemRegra.DataInicioVigencia);
                        IEnumerable<ParametroRegra> parametrosExogenosPorRegra = parametrosPorRegra.Where(p => parametrosEndogenosPorGrupo.Count(q => q.CodigoParametroAtribuicao == p.CodigoParametroAtribuicao) == 0);

                        //Curva primeiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaPrimeiraComCaixa);
                        //Curva terceiraCurva = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceira);
                        //Curva terceiraCurvaCaixa = listaCurvas.FirstOrDefault(p => p.CodigoCurva == itemRegra.CodigoCurvaTerceiraComCaixa);
                        //ProdutoFinanceiroDerivado produtoExcecao = produtosExcecaoPorGrupo.FirstOrDefault(p => p.CodigoProdutoFinanceiroDerivado == itemRegra.CodigoProdutoFinanceiroExcecao);

                        novoItemRelatorio.NomeMesaOrigem1Curva = filtroRelatorio.ListaMesaOrigem.FirstOrDefault(p => p.CodigoSubMesa == primeiraCurva.CodigoSubMesaOperacao).Nome;
                        //novoItemRelatorio.NomeCurva = primeiraCurva != null ? primeiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeCurvaComCaixa = primeiraCurvaCaixa != null ? primeiraCurvaCaixa.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeTerceiraCurva = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeTerceiraCurvaComCaixa = terceiraCurva != null ? terceiraCurva.NomeCurva : string.Empty;
                        //novoItemRelatorio.NomeProdutoExcecao = produtoExcecao != null ? produtoExcecao.NomeProdutoFinanceiroDerivado : string.Empty;

                        novoItemRelatorio.NomeGrupoParametro = filtroRelatorio.GrupoParametro.NomeGrupoParametroAtribuicao;
                        novoItemRelatorio.CodigoGrupoParametroAtribuicao = filtroRelatorio.GrupoParametro.CodigoGrupoParametroAtribuicao;
                        novoItemRelatorio.Situacao = itemRegra.CodigoSituacao == 1 ? "Habilitada" : "Desabilitada";
                        novoItemRelatorio.DataInicioVigencia = itemRegra.DataInicioVigencia;
                        novoItemRelatorio.DataFimVigencia = itemRegra.DataFimVigencia;
                        novoItemRelatorio.NomeCurva = itemRegra.NomeCurvaPrimeira;
                        novoItemRelatorio.NomeCurvaComCaixa = itemRegra.NomePrimeiraCurvaComCaixa;
                        novoItemRelatorio.NomeTerceiraCurva = itemRegra.NomeTerceiraCurva;
                        novoItemRelatorio.NomeTerceiraCurvaComCaixa = itemRegra.NomeTerceiraCurvaComCaixa;
                        novoItemRelatorio.NomeProdutoExcecao = itemRegra.NomeProdutoDerivadoExcecao;

                        switch (itemRegra.CodigoTipoPrazo)
                        {
                            case 1:
                                novoItemRelatorio.CodigoTipoPrazo = "DU";
                                break;
                            case 2:
                                novoItemRelatorio.CodigoTipoPrazo = "DC";
                                break;
                            default:
                                novoItemRelatorio.CodigoTipoPrazo = string.Empty;
                                break;
                        }
                        novoItemRelatorio.QtdeDiasPrazo = itemRegra.QuantidadeDiasPrazo;

                        foreach (var itemEndogeno in parametrosEndogenosPorGrupo)
                        {
                            ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemEndogeno.CodigoParametroAtribuicao);

                            novoItemRelatorio.ListaParametros.AddRange(ObterParametroEndogeno(itemEndogeno, parametroCompleto, dominiosPorGrupo));
                        }

                        foreach (var itemExogeno in parametrosExogenosPorRegra)
                        {
                            ParametroAtribuicao parametroCompleto = listaParametros.FirstOrDefault(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao);

                            //IList<DominioParametroAtribuicao> dominioPorParametro = relatorioParametroDAO.ObterRegistrosDominioParametro(itemExogeno.CodigoParametroAtribuicao);
                            IList<DominioParametroAtribuicao> dominioPorParametro = listaRegistroDominio.Where(p => p.CodigoParametroAtribuicao == itemExogeno.CodigoParametroAtribuicao).ToList();

                            novoItemRelatorio.ListaParametros.AddRange(ObterParametroExogeno(itemExogeno, parametroCompleto, dominioPorParametro));
                        }

                        relatorioSegregacaoRegrasSaida.Add(novoItemRelatorio);
                    }

                }

                return relatorioSegregacaoRegrasSaida;
            }
            catch (DadosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (NegociosException ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }
            catch (Exception ex)
            {
                EnterpriseLibraryFactory.GetExceptionHandler().HandleException(ex, "ErrosNegocios");
            }

            return null;
        }

        private IList<ParametroRelatorio> ObterParametroEndogeno(ParametroAtribuicaoGrupoAlocacao parametroAlocado, ParametroAtribuicao parametroCompleto, IList<DominioParametroAtribuicao> dominios)
        {
            IList<ParametroRelatorio> parametroRelatorio = new List<ParametroRelatorio>();

            if (parametroAlocado != null && parametroCompleto != null)
            {
                if (parametroAlocado.CodigoDominioParametroAtribuicao != 0)
                {
                    DominioParametroAtribuicao dominioDefinido = dominios.FirstOrDefault(p => p.CodigoDominioParametroAtribuicao == parametroAlocado.CodigoDominioParametroAtribuicao);

                    if (dominioDefinido != null)
                    {
                        parametroRelatorio.Add(new ParametroRelatorio()
                        {
                            CodigoDominio = dominioDefinido.CodigoDominioParametroAtribuicao,
                            CodigoParametro = dominioDefinido.CodigoParametroAtribuicao,
                            Valor = dominioDefinido.TextoValorDominioParametro,
                            NomeParametro = parametroCompleto.NomeParametroAtribuicao
                        });
                    }
                }
                else
                {
                    if (string.IsNullOrEmpty(parametroAlocado.TextoValorAtribuicaoFim) &&
                        string.IsNullOrEmpty(parametroAlocado.TextoValorAtribuicaoFim.Trim())) //Parâmetro sem range
                    {
                        parametroRelatorio.Add(new ParametroRelatorio()
                        {
                            Valor = parametroAlocado.TextoValorParametroAtribuicao,
                            NomeParametro = parametroCompleto.NomeParametroAtribuicao
                        });
                    }
                    else //Parâmetro com range
                    {
                        parametroRelatorio.Add(new ParametroRelatorio()
                        {
                            Valor = parametroAlocado.TextoValorParametroAtribuicao,
                            NomeParametro = string.Concat(parametroCompleto.NomeParametroAtribuicao, " - ", "Início")
                        });

                        parametroRelatorio.Add(new ParametroRelatorio()
                        {
                            Valor = parametroAlocado.TextoValorAtribuicaoFim,
                            NomeParametro = string.Concat(parametroCompleto.NomeParametroAtribuicao, " - ", "Fim")
                        });
                    }
                }
            }

            return parametroRelatorio;
        }

        private IList<ParametroRelatorio> ObterParametroExogeno(ParametroRegra parametroAlocado, ParametroAtribuicao parametroCompleto, IList<DominioParametroAtribuicao> dominios)
        {
            IList<ParametroRelatorio> parametroRelatorio = new List<ParametroRelatorio>();

            if (parametroAlocado != null && parametroCompleto != null)
            {
                if (parametroAlocado.CodigoDominioParametroAtribuicao != 0)
                {
                    DominioParametroAtribuicao dominioSelecionado = dominios.FirstOrDefault(
                        p => p.CodigoDominioParametroAtribuicao == parametroAlocado.CodigoDominioParametroAtribuicao);

                    parametroRelatorio.Add(new ParametroRelatorio()
                    {
                        CodigoDominio = dominioSelecionado.CodigoDominioParametroAtribuicao,
                        CodigoParametro = parametroCompleto.CodigoParametroAtribuicao,
                        Valor = dominioSelecionado.TextoValorDominioParametro,
                        NomeParametro = parametroCompleto.NomeParametroAtribuicao,
                    });
                }
                else
                {
                    if (string.IsNullOrEmpty(parametroAlocado.TextoValorInternoFim) &&
                        string.IsNullOrEmpty(parametroAlocado.TextoValorInternoFim.Trim())) //Parâmetro sem range
                    {
                        parametroRelatorio.Add(new ParametroRelatorio()
                        {
                            Valor = parametroAlocado.TextoValorInterno,
                            NomeParametro = parametroCompleto.NomeParametroAtribuicao,
                            CodigoParametro = parametroCompleto.CodigoParametroAtribuicao
                        });
                    }
                    else //Parâmetro com range
                    {
                        parametroRelatorio.Add(new ParametroRelatorio()
                        {
                            Valor = parametroAlocado.TextoValorInterno,
                            NomeParametro = string.Concat(parametroCompleto.NomeParametroAtribuicao, " - ", "Início"),
                            CodigoParametro = parametroCompleto.CodigoParametroAtribuicao,
                        });

                        parametroRelatorio.Add(new ParametroRelatorio()
                        {
                            Valor = parametroAlocado.TextoValorInternoFim,
                            NomeParametro = string.Concat(parametroCompleto.NomeParametroAtribuicao, " - ", "Fim"),
                            CodigoParametro = parametroCompleto.CodigoParametroAtribuicao
                        });
                    }
                }
            }

            return parametroRelatorio;
        }
    }
}
